﻿#include "StepDataDialog.h"
#include "DataTrans.h"

StepDataDialog::StepDataDialog(QWidget *parent)
	: QDialog(parent)
{
	ui.setupUi(this);	
	m_index = 0;
	m_isReal = false;

	Qt::WindowFlags flags = windowFlags();
	flags |= Qt::WindowMinMaxButtonsHint;
	flags |= Qt::WindowCloseButtonHint;
	setWindowFlags(flags);
	
	m_treeHeaderList1 << tr("记录序号") << tr("工步时间") << tr("起始电压(V)") << tr("终止电压(V)") << tr("充电中值电压(V)")
		<< tr("放电中值电压(V)") << "";
	m_treeHeaderList2 << tr("记录序号") << tr("记录时间") << tr("电压(V)") << tr("电流(A)") << tr("容量(Ah)")
		<< tr("能量(Wh)") << tr("绝对时间");	

	Q_ASSERT(m_treeHeaderList1.size() == m_treeHeaderList2.size());		
	ui.treeWidget->setColumnCount(m_treeHeaderList1.size());

	ui.treeWidget->setSelectionMode(QAbstractItemView::SingleSelection); //单击选择一行  
	ui.treeWidget->setSelectionBehavior(QAbstractItemView::SelectRows);  //设置只能选择一行，不能多行选		
	ui.treeWidget->setEditTriggers(QTableWidget::NoEditTriggers);

	ui.tabWidget->removeTab(2);

	updateTreeHeader(0);
}

StepDataDialog::~StepDataDialog()
{
}

void StepDataDialog::showEvent(QShowEvent *event)
{	
	QDialog::showEvent(event);
}

QString StepDataDialog::deviceId()
{
	return m_deviceId;
}

bool StepDataDialog::isReal()
{
	return m_isReal;
}

void StepDataDialog::updateTreeHeader(int level)
{
	if(level < 2)
		ui.treeWidget->setHeaderLabels(m_treeHeaderList1);
	else
		ui.treeWidget->setHeaderLabels(m_treeHeaderList2);
}

void StepDataDialog::init(bool real,QString deviceString,int index, BTERecordPtr recordInfo)
{
	m_isReal = real;
	m_deviceId = deviceString;
	m_index = index;
	m_recordInfo = recordInfo;
	ui.treeWidget->clear();
	updateTreeHeader(0);

	m_stepBeginVolt = m_stepEndVolt = 0;
	m_stepBeginTime = m_stepEndTime = 0;
	m_stepVolt.clear();
	m_stepCap.clear();

	if (isReal())
		setWindowTitle(tr("实时数据 ") + deviceString + QString::asprintf(" CH:%d-%d", m_index / 8 + 1, m_index % 8 + 1));
	else
	{
		setWindowTitle(tr("离线数据 ") + deviceString + QString::asprintf(" CH:%d-%d", recordInfo->info.itemIndex / 8 + 1, recordInfo->info.itemIndex % 8 + 1));
	}

	if (m_recordInfo->dataList.size() > 0)
		m_baseTime = m_recordInfo->dataList[0].ATime.toMSec();
	else
		m_baseTime = 0;

	ui.btnUpdate->setVisible(m_isReal);

	ui.label1L->setStyleSheet("color:blue;");
	ui.label2L->setStyleSheet("color:blue;");
	ui.label3L->setStyleSheet("color:blue;");
	ui.label1R->setStyleSheet("color:red;");
	ui.label2R->setStyleSheet("color:red;");
	ui.label3R->setStyleSheet("color:red;");

	ui.label1L->setText(tr("电流(A)"));
	ui.label1R->setText(tr("电压(V)"));

	ui.label2L->setText(tr("电压(V)"));
	
	ui.label3L->setText(tr("容量"));
	ui.label3R->setText(tr("比容量"));

	//plot time
	initPlot(ui.plot1, { tr("电流") , tr("电压") });
	initPlot(ui.plot3, { tr("容量") , tr("比容量") });

	ui.plot1->xAxis->setLabel(tr("时间(s)"));
	ui.plot2->xAxis->setLabel(tr("容量(Ah)"));

	ui.plot1->legend->setVisible(true);	

	//plot2 
	auto &stepList = m_recordInfo->info.stepInfo.step.stepList;
	int plot_num = 0;
		
	m_plot2Map.resize(stepList.size());
	m_plot2Map.fill(-1);

	int startStep = qMax(m_recordInfo->info.stepInfo.startStepIndex - 1, 0);
	for (int i = startStep; i < stepList.size(); i++)
	{
		if (PackDefine::StepChargeType(stepList[i].StepType) != STEP_CHARGE_OTHER)
		{
			m_plot2Map[i] = plot_num;
			plot_num++;
		}
	}

	ui.plot2->clearGraphs();
	for (int i = 0; i < plot_num; i++)
	{
		ui.plot2->addGraph();
	}
	ui.plot2->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);

	QVector<double> key_time, val1_1, val1_2, val3_1, val3_2;
	QVector<QVector<double>> key2;
	QVector<QVector<double>> val2;
	key2.resize(plot_num);
	val2.resize(plot_num);

	//tree
	int step_count = m_recordInfo->dataList.size();
	for (int i = 0; i < step_count; i++)
	{
		auto &step = m_recordInfo->dataList[i];
		if (step.StepType == STEP_TYPE_STOP || step.StepType == STEP_TYPE_NULL)
			continue;
		
		int time = (step.ATime.toMSec() - m_baseTime) / 1000;
		double current = DataTrans::fromElectricUnit(step.Current);
		double volt = DataTrans::fromVoltageUnit(step.Voltage);		
		double cap = DataTrans::fromCapUnit(step.ChargeCap);
		double dis_cap = DataTrans::fromCapUnit(step.DisChargeCap);

		int step_idx = step.StepID - 1;
		int plot2_idx = m_plot2Map[step_idx];

		//plot
		key_time.push_back(time);		
		val1_1.push_back(current);
		val1_2.push_back(volt);
		val3_1.push_back(cap);
		val3_2.push_back(volt);		

		if (plot2_idx >= 0)
		{
			if (PackDefine::StepChargeType(step.StepType) == STEP_CHARGE)
				key2[plot2_idx].push_back(cap);
			else
				key2[plot2_idx].push_back(dis_cap);

			val2[plot2_idx].push_back(volt);
		}		

		if(i < step_count - 1 && step.StepID == m_recordInfo->dataList[i+1].StepID)
			addTreeStep(step,1);
		else
			addTreeStep(step,2);
	}	
	updateLastStepItem();

	//绘制曲线
	ui.plot1->graph(0)->setData(key_time, val1_1);
	ui.plot1->graph(1)->setData(key_time, val1_2);
	ui.plot3->graph(0)->setData(key_time, val3_1);
	ui.plot3->graph(1)->setData(key_time, val3_2);

	for (int i = 0; i < ui.plot2->graphCount(); i++)	
		ui.plot2->graph(i)->setData(key2[i], val2[i]);

	on_btnPlotReset_clicked();
}

void StepDataDialog::initPlot(QCustomPlot *customPlot,QStringList names)
{		
	QSharedPointer<QCPAxisTickerTime> timeTicker(new QCPAxisTickerTime);
	timeTicker->setTimeFormat("%h:%m:%s");

	customPlot->clearGraphs();
	customPlot->xAxis->setTicker(timeTicker);
	
	customPlot->addGraph(customPlot->xAxis, customPlot->yAxis);
	customPlot->graph(0)->setPen(QPen(Qt::blue)); // line color blue for first graph

	customPlot->addGraph(customPlot->xAxis,customPlot->yAxis2);
	customPlot->graph(1)->setPen(QPen(Qt::red)); // line color red for second graph
	
	// pass data points to graphs:		
	customPlot->graph(0)->setName(names[0]);	

	if (names.size() > 1)
	{
		customPlot->graph(1)->setName(names[1]);
		customPlot->yAxis2->setVisible(true);
	}
	
	customPlot->yAxis->setBasePen(QPen(Qt::blue, 1));	
	customPlot->yAxis2->setBasePen(QPen(Qt::red, 1));

	customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);			
	customPlot->axisRect()->setRangeZoomAxes({ customPlot->xAxis }, { customPlot->yAxis,customPlot->yAxis2 });			
	customPlot->axisRect()->setRangeDragAxes({ customPlot->xAxis }, { customPlot->yAxis,customPlot->yAxis2 });

	customPlot->replot(QCustomPlot::rpQueuedReplot);
}

void StepDataDialog::rescaleAxes()
{
	ui.plot1->graph(0)->rescaleAxes(true);
	ui.plot1->graph(1)->rescaleAxes(true);
	ui.plot1->replot(QCustomPlot::rpQueuedReplot);

	for (int i = 0; i < ui.plot2->graphCount(); i++)
	{	
		ui.plot2->graph(i)->rescaleAxes(true);
	}
	ui.plot2->replot(QCustomPlot::rpQueuedReplot);

	ui.plot3->graph(0)->rescaleAxes(true);
	ui.plot3->graph(1)->rescaleAxes(true);
	ui.plot3->replot(QCustomPlot::rpQueuedReplot);
}

void StepDataDialog::addRealStep(QString deviceId,int index, const stru_BTS_CMD_SEND_DFDATA76::Data &data)
{
	//if (m_isReal && m_deviceId == deviceId && index == m_index)
	//	addStep(data);
}

void StepDataDialog::addStep(const stru_BTS_CMD_SEND_DFDATA76::Data &step)
{
	if (step.StepType == STEP_TYPE_STOP || step.StepType == STEP_TYPE_NULL)
		return;

	int time = (step.ATime.toMSec() - m_baseTime) / 1000;
	double current = DataTrans::fromElectricUnit(step.Current);
	double volt = DataTrans::fromVoltageUnit(step.Voltage);
	double cap = DataTrans::fromCapUnit(step.ChargeCap);
	double dis_cap = DataTrans::fromCapUnit(step.DisChargeCap);

	int step_idx = step.StepID - 1;	

	//plot
	ui.plot1->graph(0)->addData(time, current);
	ui.plot1->graph(1)->addData(time, volt);

	if (m_plot2Map.size() > 0)
	{
		int plot2_idx = m_plot2Map[step_idx];
		if (plot2_idx >= 0)
		{
			auto line = ui.plot2->graph(plot2_idx);
			if (PackDefine::StepChargeType(step.StepType) == STEP_CHARGE)
				line->addData(cap, volt);
			else
				line->addData(dis_cap, volt);
		}
	}

	ui.plot3->graph(0)->addData(time, cap);
	ui.plot3->graph(1)->addData(time, volt);

	rescaleAxes();

	addTreeStep(step,0);
}


void StepDataDialog::addTreeStep(const stru_BTS_CMD_SEND_DFDATA76::Data &step,int addType)
{
	//tree
	int prec = 4;	
	int top_num = ui.treeWidget->topLevelItemCount();
	int loop_time = step.CycleStatus;

	double cap = 0;
	double eng = 0;
	double volt = DataTrans::fromVoltageUnit(step.Voltage);
	int time_ms = step.ATime.toMSec();
	int charge_type = PackDefine::StepChargeType(step.StepType);

	if (charge_type == STEP_CHARGE)
	{
		cap = DataTrans::fromCapUnit(step.ChargeCap);
		eng = DataTrans::fromEngUnit(step.ChargeEng);
	}
	else if(charge_type == STEP_DISCHARGE)
	{
		cap = DataTrans::fromCapUnit(step.DisChargeCap);
		eng = DataTrans::fromEngUnit(step.DisChargeEng);
	}

	//循环项
	QTreeWidgetItem *loop_item = NULL; 
	if (loop_time >= top_num)
	{
		loop_item = new QTreeWidgetItem();
		loop_item->setText(0, "循环-" + QString::number(top_num + 1));		
		
		ui.treeWidget->addTopLevelItem(loop_item);
	}
	else
		loop_item = ui.treeWidget->topLevelItem(loop_time);

	int step_num = loop_item->childCount();
	QTreeWidgetItem *step_item = (step_num == 0)? NULL: loop_item->child(step_num - 1);
	if (!step_item || step_item->data(0,Qt::UserRole).toInt() != step.StepID)
	{		
		updateLastStepItem();

		//添加新的子项
		step_item = new QTreeWidgetItem();
		step_item->setText(0, QString::number(step_num + 1) + "-" + PackDefine::StepNameList[step.StepType]);
		step_item->setData(0, Qt::UserRole, (int)step.StepID);		
		loop_item->addChild(step_item);

		m_stepChargeType = charge_type;
		m_stepBeginVolt = volt; 
		m_stepBeginTime = time_ms; 
		m_stepVolt.clear();
		m_stepCap.clear();
	}	

	m_stepVolt.push_back(volt);
	m_stepCap.push_back(cap);
	m_stepEndVolt = volt;
	m_stepEndTime = time_ms;

	//item_num
	int item_num = step_item->childCount();
	if (step_item->childCount() > 0)
		item_num += step_item->child(0)->childCount();

	QTreeWidgetItem *sub_item = new QTreeWidgetItem();
	sub_item->setText(0, QString::number(item_num + 1));
	sub_item->setText(1, DataTrans::fromTimeUnit(step.TestTime));
	sub_item->setText(2, QString::number(volt, 'f', prec));
	sub_item->setText(3, QString::number(DataTrans::fromElectricUnit(step.Current), 'f', prec));
	sub_item->setText(4, QString::number(cap, 'f', prec));
	sub_item->setText(5, QString::number(eng, 'f', prec));	
	sub_item->setText(6, step.ATime.toString());

	/*需求要求第一项和最后一项独立显示，其他项作为在第一项的子项，但是整体添加时每次判断较慢，这里做判断*/
	if (addType == 0)  //普通情况
	{
		if (step_item->childCount() == 2)
		{
			auto last = step_item->child(1);
			step_item->removeChild(last);
			step_item->child(0)->addChild(last);
		}
		step_item->addChild(sub_item);
	}
	else
	{
		//整体添加时
		if (step_item->childCount() == 0)		
			step_item->addChild(sub_item);
		else
		{ 
			if (addType == 1)       //第一项
				step_item->child(0)->addChild(sub_item);
			else if (addType == 2)  //第二项
				step_item->addChild(sub_item);
		}		
	}
}

void StepDataDialog::on_btnPlotReset_clicked()
{
	ui.plot1->xAxis->setRange(0, 5);
	ui.plot1->yAxis->setRange(0, 5);
	ui.plot1->yAxis2->setRange(0, 5);
	
	ui.plot2->xAxis->setRange(0, 0.5);
	ui.plot2->yAxis->setRange(0, 5);
	ui.plot2->yAxis2->setRange(0, 5);

	ui.plot3->xAxis->setRange(0, 5);
	ui.plot3->yAxis->setRange(0, 5);
	ui.plot3->yAxis2->setRange(0, 5);

	rescaleAxes();
}

void StepDataDialog::on_btnUpdate_clicked()
{
	if (m_index >= 0)
		emit sigChannelChanged(m_index);
}

void StepDataDialog::on_btnUpChannel_clicked()
{
	if (m_index > 0)
		emit sigChannelChanged(m_index - 1);
}

void StepDataDialog::on_btnDownChannel_clicked()
{
	emit sigChannelChanged(m_index + 1);
}

void StepDataDialog::on_treeWidget_itemExpanded(QTreeWidgetItem *item)
{
}

void StepDataDialog::on_treeWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
{
	int level = 0;
	QTreeWidgetItem *item = current;
	while (item && item->parent())
	{
		item = item->parent();
		level++;
	}
	
	updateTreeHeader(level);
}

void StepDataDialog::on_tabWidget_currentChanged(int index)
{
	
}


void StepDataDialog::updateLastStepItem()
{
	int prec = 4;
	int count = ui.treeWidget->topLevelItemCount();

	QTreeWidgetItem *step_item = NULL;
	for (int i = count - 1; i >= 0; i--)
	{
		QTreeWidgetItem *top = ui.treeWidget->topLevelItem(i);
		if (top->childCount() > 0)
		{
			step_item = top->child(top->childCount() - 1);
			break;
		}
	}

	if (step_item)
	{
		//计算充放电中值电压
		double volt = 0;
		if (m_stepChargeType != STEP_CHARGE_OTHER && m_stepCap.size() > 0)
		{
			double var = m_stepCap.back() / 2;
			auto range = std::equal_range(m_stepCap.begin(), m_stepCap.end(), var);
			int idx = range.first - m_stepCap.begin();
			idx = qMax(idx, 0);
			idx = qMin(idx, m_stepVolt.size() - 1);

			volt = m_stepVolt[idx];
		}

		step_item->setText(1, DataTrans::fromTimeUnit(m_stepEndTime - m_stepBeginTime));
		step_item->setText(2, QString::number(m_stepBeginVolt, 'f', prec));
		step_item->setText(3, QString::number(m_stepEndVolt, 'f', prec));
		step_item->setText(4, QString::number(m_stepChargeType == STEP_CHARGE?    volt:0, 'f', prec));
		step_item->setText(5, QString::number(m_stepChargeType == STEP_DISCHARGE? volt:0, 'f', prec));
	}
}